#include "TextureUtility.h"

using namespace Renderer;


int Renderer::TextureUtility::SizeInBytes(ImageDatatype dataType)
{
	switch (dataType)
	{
	case ImageDatatype::Byte:
		return 1;
	case ImageDatatype::UnsignedByte:
		return 1;
	case ImageDatatype::Short:
		return 2;
	case ImageDatatype::UnsignedShort:
		return 2;
	case ImageDatatype::Int:
		return 4;
	case ImageDatatype::UnsignedInt:
		return 4;
	case ImageDatatype::Float:
		return 4;
	case ImageDatatype::HalfFloat:
		return 2;
	case ImageDatatype::UnsignedByte332:
		return 1;
	case ImageDatatype::UnsignedShort4444:
		return 2;
	case ImageDatatype::UnsignedShort5551:
		return 2;
	case ImageDatatype::UnsignedInt8888:
		return 4;
	case ImageDatatype::UnsignedInt1010102:
		return 4;
	case ImageDatatype::UnsignedByte233Reversed:
		return 1;
	case ImageDatatype::UnsignedShort565:
		return 2;
	case ImageDatatype::UnsignedShort565Reversed:
		return 2;
	case ImageDatatype::UnsignedShort4444Reversed:
		return 2;
	case ImageDatatype::UnsignedShort1555Reversed:
		return 2;
	case ImageDatatype::UnsignedInt8888Reversed:
		return 4;
	case ImageDatatype::UnsignedInt2101010Reversed:
		return 4;
	case ImageDatatype::UnsignedInt248:
		return 4;
	case ImageDatatype::UnsignedInt10F11F11FReversed:
		return 4;
	case ImageDatatype::UnsignedInt5999Reversed:
		return 4;
	case ImageDatatype::Float32UnsignedInt248Reversed:
		return 4;
	}


	//throw new ArgumentException("dataType");
	//TODO
	return 0;
}

int Renderer::TextureUtility::NumberOfChannels(ImageFormat format)
{
	switch (format)
	{
	case ImageFormat::StencilIndex:
		return 1;
	case ImageFormat::DepthComponent:
		return 1;
	case ImageFormat::Red:
		return 1;
	case ImageFormat::Green:
		return 1;
	case ImageFormat::Blue:
		return 1;
	case ImageFormat::RedGreenBlue:
		return 3;
	case ImageFormat::RedGreenBlueAlpha:
		return 4;
	case ImageFormat::BlueGreenRed:
		return 3;
	case ImageFormat::BlueGreenRedAlpha:
		return 4;
	case ImageFormat::RedGreen:
		return 2;
	case ImageFormat::RedGreenInteger:
		return 2;
	case ImageFormat::DepthStencil:
		return 2;
	case ImageFormat::RedInteger:
		return 1;
	case ImageFormat::GreenInteger:
		return 1;
	case ImageFormat::BlueInteger:
		return 1;
	case ImageFormat::RedGreenBlueInteger:
		return 3;
	case ImageFormat::RedGreenBlueAlphaInteger:
		return 4;
	case ImageFormat::BlueGreenRedInteger:
		return 3;
	case ImageFormat::BlueGreenRedAlphaInteger:
		return 4;
	}

	//throw new ArgumentException("format");
	//TODO
	return 0;
}

int Renderer::TextureUtility::RequiredSizeInBytes(int width, int height, ImageFormat& format, ImageDatatype& dataType, int rowAlignment)
{
	int rowSize = width * NumberOfChannels(format) * SizeInBytes(dataType);

	int remainder = (rowSize % rowAlignment);
	rowSize += (rowAlignment - remainder) % rowAlignment;

	return rowSize * height;
}

bool Renderer::TextureUtility::IsPowerOfTwo(unsigned i)
{
	return (i != 0) && ((i & (i - 1)) == 0);
}
